//
//  KDDViewConfig.m
//  MengLiao
//
//  Created by xiuxin on 2022/7/15.
//  Copyright © 2022 HZMengLiao. All rights reserved.
//

#import "KMViewConfig.h"
#import "KDDCollectionWrapper.h"
#import "NSObject+KMModel.h"
#import "KMView.h"
#import "KUIModule.h"
#import "KDDModel.h"
#define KMCreateReuseID(viewID,spec,viewType) [[NSString alloc] initWithFormat:@"%@__%@__%ld",viewID,spec,viewType]

#define KMSpecFromReuseID(reuseID) [reuseID componentsSeparatedByString:@"__"][1]

@implementation KMViewConfig

- (instancetype)initWithViewClass:(Class<KMView>)viewClass
{
    if (self = [super init])
    {
        _viewClass = viewClass;
        [self config];
    }
    return self;
}

- (void)config
{
    self.configID = [(id<KMView>)self.viewClass viewID];
    @weakify(self)
    self.wrapperClassBlock = ^Class(NSString *reuseID, KDDViewType viewType) {
        if (viewType == KDDViewTypeCell)
        {
            return [KDDCollectionCell class];
        }
        else
        {
            return [KDDCollectionHeaderFooterView class];
        }
    };
    
    BOOL multipleSpec = [(id)self.viewClass respondsToSelector:@selector(specForModel:)];
    self.reuseIDBlock = ^NSString *(NSObject * model, KDDViewType viewType) {
        @strongify(self)
        NSString * spec = multipleSpec ? [self.viewClass specForModel:model] : @"";
        return KMCreateReuseID(self.configID, spec, viewType);
    };
    
    self.sizeBlock = ^id(NSObject * model, KDDPosition *position) {
        @strongify(self)
        return [NSValue valueWithCGSize:[self.viewClass sizeForSpec:KMSpecFromReuseID(model.ddReuseID) model:model]];
    };
    
    _needDelegate = [(id)self.viewClass instancesRespondToSelector:@selector(setKmDelegate:)];
    _needLoadModel = [(id)self.viewClass instancesRespondToSelector:@selector(kmLoadModel:position:)];
    BOOL needWillDisplay = [(id)self.viewClass instancesRespondToSelector:@selector(ddWillDisplay:position:)];
    BOOL needAttributes = [(id)self.viewClass instancesRespondToSelector:@selector(applyLayoutAttributes:)];
    [self setHandler:^(__kindof UIView<KMWrapperView> *view, NSObject *model, KDDPosition *position) {
        @strongify(self)
        [self handleLoadModelEvent:view model:model position:position needWillDisplay:needWillDisplay needAttributes:needAttributes];
    } forEvent:KDDLoadModelEvent];
    
    [self setHandler:^(__kindof UIView *view, __kindof NSObject *model, KDDPosition *position) {
        if (model.kmDelegate != nil && [model.kmDelegate respondsToSelector:@selector(didSelectModel:viewID:spec:position:)])
        {
            [model.kmDelegate didSelectModel:model viewID:model.ddConfigID spec:KMSpecFromReuseID(model.ddReuseID) position:position];
        }
    } forEvent:KDDSelectModelEvent];
}

- (void)handleLoadModelEvent:(__kindof UIView<KMWrapperView> *)view model:(NSObject *)model position:(KDDPosition *)position needWillDisplay:(BOOL)needWillDisplay needAttributes:(BOOL)needAttributes
{
    UIView<KMView> * kmView = view.kmView;
    if (kmView == nil)
    {
        CGSize size = [model.ddSize CGSizeValue];
        kmView = [(id)self.viewClass addToWrapper:view frame:CGRectMake(0, 0, size.width, size.height) spec:KMSpecFromReuseID(model.ddReuseID)];
        if (self.needLoadModel)
        {
            [kmView kmLoadModel:model position:position];
        }
        if (self.needDelegate)
        {
            [kmView setKmDelegate:model.kmDelegate];
        }
        if (needAttributes && view.attributes != nil)
        {
            [kmView applyLayoutAttributes:view.attributes];
        }
        if (needWillDisplay)
        {
            [kmView ddWillDisplay:model position:position];
        }
    }
    else
    {
        if (self.needDelegate)
        {
            [kmView setKmDelegate:model.kmDelegate];
        }
        if (self.needLoadModel)
        {
            [kmView kmLoadModel:model position:position];
        }
    }
}

- (void)configModel:(NSObject *)model
{
    NSString * spec = @"";
    if ([(id)self.viewClass respondsToSelector:@selector(specForModel:)])
    {
        spec = [self.viewClass specForModel:model] ?: @"";
    }
    if (model.ddViewType != KDDViewTypeNone)
    {
        model.ddReuseID = KMCreateReuseID(self.configID, spec, model.ddViewType);
    }
    model.ddSize = [NSValue valueWithCGSize:[self.viewClass sizeForSpec:spec model:model]];
}

@end
